package com.appspot.abcensys.server.DAO.JDO;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;

import com.appspot.abcensys.server.PMF;
import com.appspot.abcensys.server.DAO.GebruikerDAO;
import com.appspot.abcensys.shared.Gebruiker;

public class GebruikerDAO_JDO implements GebruikerDAO {

	/**
	 * Logger
	 */
	private final Logger log = Logger.getLogger(GebruikerDAO_JDO.class.getName());

	/**
	 * Haalt een lijst van alle Gebruiker objecten op
	 * 
	 * @return List met Gebruiker objecten
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Gebruiker> getGebruikers() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Gebruiker.class.getName();
		ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>(pm.detachCopyAll((List<Gebruiker>) pm.newQuery(query).execute()));

		gebruikers.size();
		pm.close();

		log.info("getGebruikers() | Gebruikers: " + gebruikers);

		return gebruikers;
	}

	/**
	 * Haalt een Gebruiker a.d.v. zijn email adres op
	 * 
	 * @param String
	 *            met email adres
	 * @return Gebruiker object
	 */
	@SuppressWarnings("unchecked")
	public Gebruiker getGebruikerByEmail(String email) {

		if (email == null) {
			return null;
		}

		Gebruiker g = null;

		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Gebruiker.class.getName() + " WHERE email == \"" + email + "\"";
		ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>(pm.detachCopyAll((List<Gebruiker>) pm.newQuery(query).execute()));

		gebruikers.size();
		pm.close();

		if (gebruikers != null && !gebruikers.isEmpty()) {
			g = gebruikers.get(0);
			log.info("getGebruikerByEmail(" + email + ") | Gebruiker: " + g.toString());
		}

		log.info("getGebruikerByEmail(" + email + ")");

		return g;
	}

	/**
	 * Voegt een gebruiker toe
	 * 
	 * @param Gebruiker
	 *            gebruiker object
	 * @return Boolean
	 */
	public Gebruiker addGebruiker(Gebruiker g) {
		Gebruiker gebruiker = getGebruikerByEmail(g.getEmail());
		if (gebruiker == null) {
			PersistenceManager pmWrite = PMF.get().getPersistenceManager();
			try {
				pmWrite.makePersistent(g);
			} finally {
				pmWrite.close();
			}
		}

		log.info("addGebruiker(" + g.toString() + ") | Gebruiker: " + g.toString());

		return g;
	}

	/**
	 * Update een Gebruiker object
	 * 
	 * @param Gebruiker
	 *            het gebruiker object die geupdate word
	 * @return Gebruiker object die ontvangen is
	 */
	public Gebruiker updateGebruiker(Gebruiker g) {
		Gebruiker gebruiker = getGebruikerByEmail(g.getEmail());
		if (gebruiker.getClass() == Gebruiker.class) {
			PersistenceManager pmWrite = PMF.get().getPersistenceManager();
			try {
				pmWrite.makePersistent(g);
			} finally {
				pmWrite.close();
			}
		}

		log.info("updateGebruiker(" + g.toString() + ") | Gebruiker: " + g.toString());

		return g;
	}

	/**
	 * Dummy classe
	 */
	public boolean deleteGebruiker(Gebruiker g) {
		return false;
	}

	/**
	 * Haalt een Gebruiker object op a.d.v. een docentCode
	 * 
	 * @param String
	 *            docentCode die opgehaald moet worden
	 * @return Gebruiker die opgehaald word, anders null
	 */
	@SuppressWarnings("unchecked")
	public Gebruiker getGebruikerByDocentCode(String docentCode) {
		if (docentCode == null) {
			return null;
		}

		Gebruiker g = null;

		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Gebruiker.class.getName() + " WHERE docentCode == '" + docentCode + "'";
		ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>(pm.detachCopyAll((List<Gebruiker>) pm.newQuery(query).execute()));

		gebruikers.size();
		pm.close();

		if (gebruikers != null && !gebruikers.isEmpty()) {
			g = gebruikers.get(0);
		}

		log.info("getGebruikerByDocentCode(" + docentCode + ") | Gebruiker: " + g.toString());

		return g;
	}

	/**
	 * Haalt alle docenten op
	 * 
	 * @return List<Gebruiker> met alle docentgen, null wanneer leeg
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Gebruiker> getDocenten() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Gebruiker.class.getName() + " WHERE type == '" + Gebruiker.TYPE_DOCENT + "'";
		ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>(pm.detachCopyAll((List<Gebruiker>) pm.newQuery(query).execute()));

		gebruikers.size();
		pm.close();

		log.info("getDocenten() | Gebruikers: " + gebruikers);

		return gebruikers;
	}

	/**
	 * Haalt een Gebruiker op a.d.v. zijn voor en achternaam
	 * 
	 * @param String
	 *            voornaam
	 * @param String
	 *            achternaam
	 * @return Gebruiker wanneer gevonden, anders null
	 */
	@SuppressWarnings("unchecked")
	public Gebruiker getGebruikerByVoorAndAchternaam(String voornaam, String achternaam) {
		Gebruiker g = null;

		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Gebruiker.class.getName() + " WHERE voornaam == \"" + voornaam + "\" && achternaam == \"" + achternaam + "\"";
		ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>(pm.detachCopyAll((List<Gebruiker>) pm.newQuery(query).execute()));

		gebruikers.size();
		pm.close();

		if (gebruikers != null && !gebruikers.isEmpty()) {
			g = gebruikers.get(0);
			
			log.info("getGebruikerByVoorAndAchternaam(" + voornaam + ", " + achternaam + ") | Gebruikers: " + g.toString());
		}

		log.info("getGebruikerByVoorAndAchternaam(" + voornaam + ", " + achternaam + ") ");
		
		return g;
	}
	
	/**
	 * Haalt Gebruiker objecten op a.d.v. een klascode
	 * 
	 * @param String met klascode
	 * @return ArrayList<Gebruiker> met Gebruiker objecten
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Gebruiker> getGebruikersByKlascode(String klascode) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "SELECT FROM " + Gebruiker.class.getName() + " WHERE klasCode == \"" + klascode + "\"";
		ArrayList<Gebruiker> gebruikers = new ArrayList<Gebruiker>(pm.detachCopyAll((List<Gebruiker>) pm.newQuery(query).execute()));
		
		gebruikers.size();
		pm.close();
		
		return gebruikers;
	}
	
	/**
	 * Haalt het aantal Gebruiker objecten op a.d.v. een klascode
	 *
	 * @param String met klascode
	 * @return int met aantal Gebruiker objecten
	 */
	public int getAantalGebruikersByKlascode(String klascode) {
		return getGebruikersByKlascode(klascode).size();
	}
}
